/*
 * (C) Copyright 2015-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Contributors:
 *     ohun@live.cn (夜色)
 */

package com.shinemo.mpush.alloc;

import java.io.IOException;
import java.util.Map;

import com.mpush.api.chat.ChatMessage;
import com.mpush.api.push.*;
import com.shinemo.mpush.alloc.service.chat.IosPushService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mpush.api.chat.ChatMessageSendResult;
import com.mpush.api.protocol.PushType;
import com.mpush.netty.http.HttpClient;
import com.mpush.tools.Jsons;
import com.mpush.tools.common.Strings;
import com.shinemo.mpush.alloc.common.ResultCode;
import com.shinemo.mpush.alloc.http.HttpRequest;
import com.shinemo.mpush.alloc.http.HttpResponse;
import com.shinemo.mpush.alloc.service.MesIdService;
import com.shinemo.mpush.alloc.service.MessageService;
import com.shinemo.mpush.alloc.service.chat.MemberService;
import com.shinemo.mpush.alloc.vo.ChatMessageResponse;
import com.shinemo.mpush.alloc.vo.MemberListResponse;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;

/**
 * Created by ohun on 16/9/7.
 *
 * @author ohun@live.cn (夜色)
 */
/* package */ final class PushHandler implements HttpHandler {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    private PushSender pushSender = null;
    private HttpClient httpClient = null;
    private MesIdService mesIdService = null;
    private IosPushService iosPushService=null;
    private MessageService messageService = new MessageService();
    private MemberService memberService = new MemberService();
    private String note = "有人给您发了一条消息！";

    public PushHandler(PushSender pushSender, HttpClient httpClient, MesIdService mesIdService,IosPushService iosPushService) {
        this.pushSender = pushSender;
        this.httpClient = httpClient;
        this.mesIdService = mesIdService;
        this.iosPushService=iosPushService;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void handle(HttpExchange httpExchange) throws IOException {
        ChatMessageResponse response = new ChatMessageResponse();
        try {

            String signHeader = HttpRequest.getSignHeader(httpExchange);

            logger.info("signHeader:{}",signHeader);

            String body = HttpRequest.getBody(httpExchange);
            logger.info("接收到的消息:{}", body);
            Map<String, Object> params = HttpRequest.toMap(body);

            response = this.sendPush(params);
        } catch (Exception e) {
            logger.error("", e);
            response.setCode(ResultCode.INTERNAL_SERVER_ERROR.getCode());
            response.setMes("内部错误");
        }
        HttpResponse.writeJson(httpExchange, Jsons.toJson(response));

    }

    private ChatMessageResponse sendPush(Map<String, Object> params) {

        String json = Jsons.toJson(params);

        logger.info("接收到的消息:{}", json);

        Long sendTime = System.currentTimeMillis();
        ChatMessageResponse response = Jsons.fromJson(json, ChatMessageResponse.class);
        response.setSendTime(sendTime);


        ChatMessage chatMessage = Jsons.fromJson(json, ChatMessage.class);
        chatMessage.setSendTime(sendTime);

        if (chatMessage.getSenderId() == null || "".equals(chatMessage.getSenderId().trim())) {
            response.setCode(ResultCode.PARAM_VALIDATE.getCode());
            response.setMes("发送者ID不能为空");
            return response;
        }

        Long sessionId = chatMessage.getSessionId();
        if (null == sessionId) {
            response.setCode(ResultCode.PARAM_VALIDATE.getCode());
            response.setMes("会话ID不能为空");
            return response;
        }

        MemberListResponse list = memberService.list(sessionId);

        if (list.getCode() == ResultCode.SUCCESS.getCode() && !list.getData().isEmpty()) {

            list.getData().stream().filter(a -> !a.getUserId().equals(chatMessage.getSenderId())).forEach(a -> {
                ChatMessage clone = chatMessage.clone();
                clone.setReceiverId(a.getUserId());
                clone.setReceiverName(a.getUserName());

                String mesId = mesIdService.createMesId();
                sendChatMessage(clone, mesId);

            });
            response.setCode(ResultCode.SUCCESS.getCode());
            response.setMes("成功");
        } else {
            response.setCode(ResultCode.INTERNAL_SERVER_ERROR.getCode());
            response.setMes("内部错误!");
            return response;
        }

        return response;
    }

    private void sendChatMessage(ChatMessage message, String mesId) {

        PushContent pushContent = new PushContent(PushType.CHAT, Jsons.toJson(message));
        PushMsg pushMsg = PushMsg.build(MsgType.NOTIFICATION_AND_MESSAGE, Jsons.toJson(pushContent));
        pushMsg.setMsgId(mesId);

        iosPushService.push(message.getSessionId(),message.getReceiverId(),note);

        pushSender.send(PushContext.build(pushMsg)
                .setUserId(Strings.isBlank(message.getReceiverId()) ? null : message.getReceiverId())
                .setCallback(new PushCallback() {
                    @Override
                    public void onResult(PushResult result) {

                        /** 失败保存数据到数据库 */
                        if (result.getResultCode() != PushResult.CODE_SUCCESS) {
                            try {
                                messageService.saveMsg(httpClient, message, ChatMessageSendResult.FAILED);
                            } catch (Exception e) {
                                logger.error("saveMsg ex, message=" + message, e);
                            }
                        }

                        logger.info(result.toString());
                    }
                }));
    }

}
